package com.hmdp.service.impl;

import cn.hutool.json.JSONUtil;
import com.hmdp.dto.Result;
import com.hmdp.entity.ShopType;
import com.hmdp.mapper.ShopTypeMapper;
import com.hmdp.service.IShopTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.hmdp.utils.RedisConstants.CACHE_SHOP_TYPE_KEY;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 虎哥
 * @since 2021-12-22
 */
@Service
public class ShopTypeServiceImpl extends ServiceImpl<ShopTypeMapper, ShopType> implements IShopTypeService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Override
    public Result queryList() {
        // 定义Redis中存储商铺类型列表的键名
        String redisKey = CACHE_SHOP_TYPE_KEY;

        // 第一步：尝试从Redis缓存中获取数据
        // 使用ZSet（有序集合）来存储，range(0, -1)表示获取所有元素
        Set<String> cachedData = stringRedisTemplate.opsForZSet().range(redisKey, 0, -1);

        // 第二步：检查缓存中是否有数据
        if (cachedData != null && !cachedData.isEmpty()) {
            // 第三步：缓存中有数据，直接使用
            // 创建一个空列表来存放最终结果
            List<ShopType> result = new ArrayList<>();

            // 遍历缓存中的每一个JSON字符串
            for (String json : cachedData) {
                // 把JSON字符串转换成ShopType对象
                ShopType shopType = JSONUtil.toBean(json, ShopType.class);
                // 添加到结果列表中
                result.add(shopType);
            }

            // 返回成功结果
            return Result.ok(result);
        }

        // 第四步：缓存中没有数据，从数据库查询
        // 按照sort字段升序排列查询所有商铺类型
        List<ShopType> dbData = this.query().orderByAsc("sort").list();

        // 第五步：检查数据库中是否有数据
        if (dbData == null || dbData.isEmpty()) {
            // 数据库也没有数据，返回失败信息
            return Result.fail("未找到商铺类型");
        }

        // 第六步：数据库有数据，保存到Redis缓存中
        // 遍历数据库查询结果
        for (int i = 0; i < dbData.size(); i++) {
            // 把ShopType对象转换成JSON字符串
            String json = JSONUtil.toJsonStr(dbData.get(i));
            // 添加到Redis的ZSet中，使用索引作为排序分数
            stringRedisTemplate.opsForZSet().add(redisKey, json, i);
        }

        // 第七步：返回数据库查询的结果
        return Result.ok(dbData);
    }

}


